package jp.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import org.cybergarage.http.HTTPPacket;
import org.cybergarage.http.HTTPRequest;
import org.cybergarage.http.HTTPRequestListener;
import org.cybergarage.http.HTTPResponse;
import org.cybergarage.http.HTTPServerList;
import org.cybergarage.http.HTTPSocket;
import org.cybergarage.http.SecureHTTPServerList;
import org.cybergarage.upnp.UPnP;
import org.geed.testbed.sub1.FooPacket;
import org.geed.testbed.sub1.FooUSocket;
import org.geed.testbed.sub1.FooUnicastListener;
import org.geed.testbed.sub1.FooUnicastServer;
import org.geed.util.UPnPCipher;

import sun.misc.BASE64Decoder;

public class Server implements HTTPRequestListener{

	private String keyAStr = "thisaboothisaboo";
	private String keyDStr = "thisabaathisabaa";
	
	//private String hostA = "192.168.0.101";
	//private int portA = 4556;
	private String hostD = "172.30.129.31";
	private int portD = 4559;

	
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Server s = new Server();
		s.start();
	}
	
	public void httpRequestRecieved(HTTPRequest httpReq){
		System.out.println("Request ====>\n"+httpReq.toString());
		String encContentFromA = httpReq.getContentString();
		
		String content = readA(encContentFromA);
		String encContentToD = enc2D(content);
		
		httpReq.setContent(encContentToD, true);
		
		Socket postSock;
		
		HTTPResponse httpRes = new HTTPResponse();
		try{
			postSock = new Socket(hostD, portD);
			OutputStream out = postSock.getOutputStream();
			PrintStream pout = new PrintStream(out);
			
			System.out.println("\n\nForward ====>\n"+httpReq.toString());
			pout.print(httpReq.toString());
			pout.flush();
			
			//response here

			HTTPSocket sock = new HTTPSocket(postSock);
			
			httpRes.read(sock);
			
			System.out.println("Response ====>\n"+httpRes.toString());
			
			String encResp = httpRes.getContentString();
			String resp = readB(encResp);
			httpRes.setContent(resp, true);
			System.out.println("Response(dec) ====>\n"+httpRes.toString());
			
			//re encode
			String encFw = enc2A(resp);
			httpRes.setContent(encFw, true);
			
			httpReq.post(httpRes);
			
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			
			
		}
	}
	
	public void start(){
		
////////////////////////////////////////
		// HTTP Server
		////////////////////////////////////////
		
		int retryCnt = 0;
		int bindPort = 4557;
		HTTPServerList httpServerList = new HTTPServerList();
		while (httpServerList.open(bindPort) == false) {
			retryCnt++;
			if (UPnP.SERVER_RETRY_COUNT < retryCnt)
				return ;
			//setHTTPPort(bindPort + 1);
			//bindPort = getHTTPPort();
		}
		httpServerList.addRequestListener(this);
		httpServerList.start();

		
		/*
		String hostD = "192.168.0.100";
		int portD = 4559;
	
		
		try{
			//start server
			ServerSocket ss = new ServerSocket(4557);
			
			while(true){
				//acepted and read
				Socket s = ss.accept();
				String request = "Host "+s.getInetAddress() + "port "+s.getPort();
				InputStream in = s.getInputStream();
				
			
				byte[] read = new byte[2048];
				int bytes_read;
				String dataStr = null;
				
				bytes_read = in.read(read);
				dataStr = new String (read, 0, bytes_read);
				
				//debug
				//request += "data===>"+dataStr;
				
				System.out.println("accept ===>"+dataStr);
				*/
		
		
				/*
				//decrypt dataStr
				String oriData = readA(dataStr);
				
				//debug
				request += "data===>"+oriData;
				
				String enc2DStr = enc2D(oriData);
				
				Socket postSock = new Socket(hostD, portD);
				OutputStream out = postSock.getOutputStream();
				PrintStream pout = new PrintStream(out);
				
				pout.print(enc2DStr);
				pout.flush();
				
				
				System.out.println(request);
				s.close();
				*/
		
		
		/*
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			
		}
		*/
		
	}
	
	
	public String readA(String enc){

		return UPnPCipher.decode(this.keyAStr.getBytes(), enc);
	}
	
	public String readB(String enc){

		return UPnPCipher.decode(this.keyAStr.getBytes(), enc);
	}
	
	public String enc2D(String ori){

		return UPnPCipher.encode(this.keyAStr.getBytes(), ori);
	}
	
	public String enc2A(String ori){

		return UPnPCipher.encode(this.keyAStr.getBytes(), ori);
	}

}
